﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text;
using System.Threading;
using System.Web.UI;
using AmazonCommon.Amazon.ECS;
using AmazonCommon;

using System.Web;
using Microsoft.Practices.EnterpriseLibrary.Caching;

/// <summary>
/// Summary description for AmazonHelper
/// </summary>
public class AmazonHelper
{

    #region Properties
    public static string associateTag
    {
        get
        {
            return CurrentAccount.AssociateTag;
        }
    }

    public static string accessKey
    {
        get
        {
            return CurrentAccount.AssociateKey;
        }
    }

    public static string secretKey
    {
        get
        {
            return CurrentAccount.SecretKey;
        }
    }


    public static AmazonAccount CurrentAccount
    {
        get
        {
            return PortalHelper.GetCurrentAccount();
        }
    }

    public static int showItemsPerPage
    {
        get
        {
            return ItemsPerPage;
        }
    }
    #endregion

    #region constants
    const int ItemsPerPage = 9;
    #endregion



    private static System.Web.Caching.Cache WebCache = HttpRuntime.Cache;


    private static DateTime lastCallToAmazonClient = DateTime.MinValue;

    public static bool clientCanBeCalledAgain
    {
        get
        {
            DateTime now = DateTime.Now;
            TimeSpan spanFromLastCall = now.Subtract(lastCallToAmazonClient);
            double millisecondsFromLastCall = spanFromLastCall.TotalMilliseconds;
            double intervalBetweenCalls = 1250;
            if (millisecondsFromLastCall < intervalBetweenCalls)
            {
                double difference = intervalBetweenCalls - millisecondsFromLastCall;
                Thread.Sleep((int)difference);
            }
            lastCallToAmazonClient = DateTime.Now;
            return true;
        }
    }

    private static CacheManager _dbCache;

    public static CacheManager DBCache
    {
        get
        {
            if (_dbCache == null)
            {

                _dbCache = CacheFactory.GetCacheManager() as CacheManager;

            }
            return _dbCache;
        }
    }

    //public static ListLookupResponse GetListManiaListInfo(string listManiaListId)
    //{
    //    AWSECommerceServicePortTypeClient client = AmazonHelper.GetAmazonClient();
    //    ListLookup listManiaListLookup = AmazonHelper.CreateListManiaListLookup(listManiaListId);
    //    ListLookupResponse result = client.ListLookup(listManiaListLookup);
    //    return result;
    //}

    //private static ListLookup CreateListManiaListLookup(string listManiaListId)
    //{
    //    ListLookup result = new ListLookup();
    //    result.AWSAccessKeyId = accessKey;
    //    result.AssociateTag = associateTag;
    //    ListLookupRequest request = new ListLookupRequest();
    //    request.ListId = listManiaListId;
    //    request.ListType = ListLookupRequestListType.Listmania;
    //    request.ListTypeSpecified = true;
    //    request.ResponseGroup = new string[] { "ListFull" };
    //    result.Request = new ListLookupRequest[] { request };
    //    return result;
    //}

    public static Items SearchProductsByCategory(string category, string keyword, int page, string sortvalue)
    {
        Items result = null;
        AWSECommerceServicePortTypeClient client = AmazonHelper.GetAmazonClient();


        ItemSearchRequest itemSearchRequest = new ItemSearchRequest();
        itemSearchRequest.SearchIndex = category;
        itemSearchRequest.Keywords = keyword;
        itemSearchRequest.ResponseGroup = new string[] { "Large", "Offers", "EditorialReview" };
        itemSearchRequest.MerchantId = "All";
        if (page != 0)
        {
            itemSearchRequest.ItemPage = page.ToString();
        }
        //itemSearchRequest.c = AmazonHelper.ItemsPerPage.ToString();
        itemSearchRequest.Availability = ItemSearchRequestAvailability.Available;
        itemSearchRequest.Condition = Condition.All;

        if (category != "All")
        {
            if (!string.IsNullOrEmpty(sortvalue))
            {
                itemSearchRequest.Sort = sortvalue;
            }
        }

        // set a default search term if one is not specified
        //TODO
        //if (this.keywords.Trim().Length == 0)
        //{
        //    itemSearchRequest.Keywords = Global.getDefaultKeyword(this.category);
        //}
        ItemSearch itemSearch = AmazonHelper.CreateItemSearch(itemSearchRequest);

        ItemSearchResponse itemSearchResponse = client.ItemSearch(itemSearch);

        if (itemSearchResponse != null)
        {
            result = itemSearchResponse.Items[0];
        }
        return result;
    }

    public static Items GetProductsForNode(string chosenNodeid, string searchIndex, string sortby, string page)
    {
        Items result = null;
        string cacheKey = chosenNodeid + searchIndex + "GetProductsForNode" + sortby + page;

        result = WebCache[cacheKey] as Items;
        if (result == null)
        {
            result = GetProductsForNodeFromAmazon(chosenNodeid, searchIndex, sortby, page);
            WebCache.Add(cacheKey, result, null, DateTime.MaxValue, ProductDetailsCacheExpiration, System.Web.Caching.CacheItemPriority.Normal, null);
        }
        else
        {

        }
        return result;
    }


    public static Items GetTopSellersForNode(string chosenNodeid, string searchIndex)
    {


        Items result = null;
        string cacheKey = chosenNodeid + searchIndex + "GetTopSellersForNode";

        result = WebCache[cacheKey] as Items;
        if (result == null)
        {
            result = GetTopSellersForNodeFromAmazon(chosenNodeid, searchIndex);
            WebCache.Add(cacheKey, result, null, DateTime.MaxValue, TimeSpan.FromMinutes(5), System.Web.Caching.CacheItemPriority.Low, null);
        }
        return result;
    }

    private static Items GetTopSellersForNodeFromAmazon(string chosenNodeid, string searchIndex)
    {
        try
        {

            Items result = null;
            BrowseNodeLookupRequest request = new BrowseNodeLookupRequest();

            // Create ItemSearch wrapper
            BrowseNodeLookup nodeLookup = new BrowseNodeLookup();
            nodeLookup.AssociateTag = associateTag;
            nodeLookup.AWSAccessKeyId = accessKey;
            request.BrowseNodeId = new string[] { chosenNodeid };
            request.ResponseGroup = new string[] { "TopSellers" };

            nodeLookup.Request = new BrowseNodeLookupRequest[] { request };

            AWSECommerceServicePortTypeClient client = AmazonHelper.GetAmazonClient();
            BrowseNodeLookupResponse response = client.BrowseNodeLookup(nodeLookup);
            List<string> topsellerAsins = new List<string>();
            foreach (BrowseNodes parentNode in response.BrowseNodes)
            {
                if (parentNode.BrowseNode != null)
                {
                    foreach (BrowseNode childNode in parentNode.BrowseNode)
                    {
                        foreach (var item in childNode.TopSellers)
                        {
                            topsellerAsins.Add(item.ASIN);
                        }
                    }
                }
            }

            //getting all the items at once
            ItemLookupRequest itemLookupRequest = new ItemLookupRequest();
            itemLookupRequest.ItemId = topsellerAsins.ToArray();
            itemLookupRequest.Condition = Condition.All;
            itemLookupRequest.ResponseGroup = GetItemLookupResponseGroupsForList();
            itemLookupRequest.IdType = ItemLookupRequestIdType.ASIN;
            itemLookupRequest.MerchantId = "All";
            //itemLookupRequest.ReviewSort = "-HelpfulVotes";
            ItemLookup itemLookup = CreateItemLookup(itemLookupRequest);
            AWSECommerceServicePortTypeClient itemLookupClient = GetAmazonClient();
            ItemLookupResponse itemLookupResponse = itemLookupClient.ItemLookup(itemLookup);


            return result = itemLookupResponse.Items[0];

        }
        catch (Exception)
        {

            return null;
        }
    }


    public static Items GetProductsForNodeFromAmazon(string chosenNodeid, string searchIndex, string sortby, string page)
    {
        AWSECommerceServicePortTypeClient client = GetAmazonClient();
        // Create ItemSearch wrapper
        ItemSearch itemSearch = new ItemSearch();
        itemSearch.AssociateTag = associateTag;
        itemSearch.AWSAccessKeyId = accessKey;


        ItemSearchRequest itemSearchRequest = new ItemSearchRequest();
        List<string> responseGroups = new List<string>();
        responseGroups.Add("Large");
        responseGroups.Add("Offers");
        responseGroups.Add("Reviews");

        itemSearchRequest.ResponseGroup = responseGroups.ToArray();
        itemSearchRequest.MerchantId = "All";
        //itemSearchRequest.Count = showItemsPerPage.ToString();
        itemSearchRequest.Availability = ItemSearchRequestAvailability.Available;
        itemSearchRequest.Condition = Condition.All;
        itemSearchRequest.Sort = sortby;
        itemSearchRequest.ItemPage = page;
        if (searchIndex != "DigitalMusic")
        {
            itemSearchRequest.BrowseNode = chosenNodeid;
        }
        else
        {
            itemSearchRequest.Keywords = "MP3";
        }

        itemSearchRequest.SearchIndex = searchIndex;
        itemSearch.Request = new ItemSearchRequest[] { itemSearchRequest };


        Items result = null;

        ItemSearchResponse itemSearchResponse = client.ItemSearch(itemSearch);

        result = itemSearchResponse.Items[0];

        return result;
    }

    private static string NodeNameToSearchIndex(string nodeName)
    {
        Dictionary<string, string> NodeNamesAndSearchIndex = new Dictionary<string, string>();
        NodeNamesAndSearchIndex.Add("Apparel", "Apparel");
        NodeNamesAndSearchIndex.Add("Automotive", "Automotive");
        NodeNamesAndSearchIndex.Add("Baby Products", "Baby");
        NodeNamesAndSearchIndex.Add("Beauty", "Beauty");
        NodeNamesAndSearchIndex.Add("Books", "Books");
        NodeNamesAndSearchIndex.Add("Camera & Photo", "Photo");
        NodeNamesAndSearchIndex.Add("Cell Phones & Service", "Wireless");
        NodeNamesAndSearchIndex.Add("Cell Phones Accessories", "WirelessAccessories");
        NodeNamesAndSearchIndex.Add("Classical Music", "Classical");
        NodeNamesAndSearchIndex.Add("DVD", "DVD");
        NodeNamesAndSearchIndex.Add("Electronics", "Electronics");
        NodeNamesAndSearchIndex.Add("Gourmet Food", "GourmetFood");
        NodeNamesAndSearchIndex.Add("Health & Personal Care", "HealthPersonalCare");
        NodeNamesAndSearchIndex.Add("Home & Garden", "Kitchen");
        NodeNamesAndSearchIndex.Add("Jewelry & Watches", "Jewelry");
        NodeNamesAndSearchIndex.Add("Magazines & Newspapers", "Magazines");
        NodeNamesAndSearchIndex.Add("Music", "Music");
        NodeNamesAndSearchIndex.Add("Musical Instruments", "MusicalInstruments");
        NodeNamesAndSearchIndex.Add("Office Products", "OfficeProducts");
        NodeNamesAndSearchIndex.Add("PC Hardware", "PCHardware");
        NodeNamesAndSearchIndex.Add("Pet Supplies", "PetSupplies");
        NodeNamesAndSearchIndex.Add("Restaurants", "Restaurants");
        NodeNamesAndSearchIndex.Add("Software", "Software");
        NodeNamesAndSearchIndex.Add("Sports & Outdoors", "SportingGoods");
        NodeNamesAndSearchIndex.Add("Tools & Hardware", "Tools");
        NodeNamesAndSearchIndex.Add("Toys & Games", "Toys");
        NodeNamesAndSearchIndex.Add("VHS", "VHS");
        NodeNamesAndSearchIndex.Add("Video", "Video");
        NodeNamesAndSearchIndex.Add("Video Games", "VideoGames");
        NodeNamesAndSearchIndex.Add("Kindle Store", "Books");
        NodeNamesAndSearchIndex.Add("MP3 Downloads ", "MP3Downloads");
        if (NodeNamesAndSearchIndex.ContainsKey(nodeName))
        {
            return NodeNamesAndSearchIndex[nodeName];
        }
        else
        {
            return "Apparel";
        }

    }

    public static string[] GetSortValuesForSearchIndex(string searchIndex)
    {
        if (SearchIndexWithSortValues.ContainsKey(searchIndex))
        {
            return SearchIndexWithSortValues[searchIndex];
        }
        else
        {
            return new string[0] { };

        }

    }

    private static Dictionary<string, string[]> searchIndexWithSortValues;

    public static Dictionary<string, string[]> SearchIndexWithSortValues
    {
        get
        {
            if (searchIndexWithSortValues == null)
            {
                searchIndexWithSortValues = LoadSearchIndexWithSortValues();
            }
            return searchIndexWithSortValues;
        }
    }

    private static Dictionary<string, string[]> LoadSearchIndexWithSortValues()
    {
        string[] sortStrings;
        searchIndexWithSortValues = new Dictionary<string, string[]>();

        sortStrings = new string[6] { "relevancerank", "salesrank", "pricerank", "inverseprice", "-launch-date", "sale-flag" };
        searchIndexWithSortValues.Add("Apparel", sortStrings);

        sortStrings = new string[5] { "salesrank", "price", "-price", "titlerank", "-titlerank" };
        searchIndexWithSortValues.Add("Automotive", sortStrings);

        sortStrings = new string[5] { "psrank", "salesrank", "price", "-price", "titlerank" };
        searchIndexWithSortValues.Add("Baby", sortStrings);

        sortStrings = new string[6] { "pmrank", "salesrank", "price", "-price", "-launch-date", "sale-flag" };
        searchIndexWithSortValues.Add("Beauty", sortStrings);

        sortStrings = new string[8] { "relevancerank", "salesrank", "reviewrank", "pricerank", "inverse-pricerank", "daterank", "titlerank", "-titlerank" };
        searchIndexWithSortValues.Add("Books", sortStrings);

        sortStrings = new string[11] { "psrank", "salesrank", "price", "-price", "titlerank", "-titlerank", "titlerank", "orig-rel-date", "-orig-rel-date", "releasedate", "-releasedate" };
        searchIndexWithSortValues.Add("Classical", sortStrings);

        sortStrings = new string[2] { "songtitlerank", "uploaddaterank" };
        searchIndexWithSortValues.Add("DigitalMusic", sortStrings);

        sortStrings = new string[7] { "relevancerank", "salesrank", "price", "-price", "titlerank", "-video-release-date", "-releasedate" };
        searchIndexWithSortValues.Add("DVD", sortStrings);

        sortStrings = new string[6] { "pmrank", "salesrank", "reviewrank", "price", "-price", "titlerank" };
        searchIndexWithSortValues.Add("Electronics", sortStrings);

        sortStrings = new string[6] { "relevancerank", "salesrank", "pricerank", "inverseprice", "launch-date", "sale-flag" };
        searchIndexWithSortValues.Add("GourmetFood", sortStrings);

        sortStrings = new string[6] { "relevancerank", "salesrank", "pricerank", "inverseprice", "launch-date", "sale-flag" };
        searchIndexWithSortValues.Add("Grocery", sortStrings);

        sortStrings = new string[6] { "pmrank", "salesrank", "pricerank", "inverseprice", "launch-date", "sale-flag" };
        searchIndexWithSortValues.Add("HealthPersonalCare", sortStrings);

        sortStrings = new string[5] { "salesrank", "price", "-price", "titlerank", "-titlerank" };
        searchIndexWithSortValues.Add("HomeGarden", sortStrings);

        sortStrings = new string[6] { "pmrank", "salesrank", "price", "-price", "titlerank", "-titlerank" };
        searchIndexWithSortValues.Add("Industrial", sortStrings);

        sortStrings = new string[5] { "pmrank", "salesrank", "pricerank", "inverseprice", "launch-date" };
        searchIndexWithSortValues.Add("Jewelry", sortStrings);

        sortStrings = new string[6] { "daterank", "-edition-sales-velocity", "price", "-price", "relevancerank", "reviewrank" };
        searchIndexWithSortValues.Add("KindleStore", sortStrings);

        sortStrings = new string[6] { "pmrank", "salesrank", "price", "-price", "titlerank", "-titlerank" };
        searchIndexWithSortValues.Add("Kitchen", sortStrings);

        sortStrings = new string[7] { "subslot-salesrank", "reviewrank", "price", "-price", "daterank", "titlerank", "-titlerank" };
        searchIndexWithSortValues.Add("Magazines", sortStrings);

        sortStrings = new string[5] { "-launch-date", "launch-date", "pricerank", "relevance", "salesrank" };
        searchIndexWithSortValues.Add("Merchants", sortStrings);

        sortStrings = new string[6] { "pmrank", "salesrank", "price", "-price", "titlerank", "-titlerank" };
        searchIndexWithSortValues.Add("Miscellaneous", sortStrings);

        sortStrings = new string[5] { "price", "-price", "-releasedate", "relevancerank", "salesrank" };
        searchIndexWithSortValues.Add("MP3Downloads", sortStrings);

        sortStrings = new string[11] { "psrank", "salesrank", "price", "-price", "titlerank", "-titlerank", "artistrank", "orig-rel-date", "release-date", "releasedate", "-releasedate" };
        searchIndexWithSortValues.Add("Music", sortStrings);

        sortStrings = new string[6] { "pmrank", "salesrank", "price", "-price", "-launch-date", "sale-flag" };
        searchIndexWithSortValues.Add("MusicalInstruments", sortStrings);

        sortStrings = new string[2] { "titlerank", "-titlerank" };
        searchIndexWithSortValues.Add("MusicTracks", sortStrings);

        sortStrings = new string[6] { "pmrank", "salesrank", "reviewrank", "price", "-price", "titlerank" };
        searchIndexWithSortValues.Add("OfficeProducts", sortStrings);

        sortStrings = new string[6] { "psrank", "salesrank", "price", "-price", "titlerank", "-titlerank" };
        searchIndexWithSortValues.Add("OutdoorLiving", sortStrings);

        sortStrings = new string[5] { "psrank", "salesrank", "price", "-price", "titlerank" };
        searchIndexWithSortValues.Add("PCHardware", sortStrings);

        sortStrings = new string[6] { "+pmrank", "salesrank", "price", "-price", "titlerank", "-titlerank" };
        searchIndexWithSortValues.Add("PetSupplies", sortStrings);

        sortStrings = new string[6] { "pmrank", "salesrank", "price", "-price", "titlerank", "-titlerank" };
        searchIndexWithSortValues.Add("Photo", sortStrings);

        sortStrings = new string[6] { "-launch-date", "pmrank", "xsrelevancerank", "price", "-price", "reviewrank" };
        searchIndexWithSortValues.Add("Shoes", sortStrings);

        //sortStrings = new string[6] { "relevancerank", "salesrank", "pricerank", "inverseprice", "-launch-date", "sale-flag" };
        //searchIndexWithSortValues.Add("SilverMerchants", sortStrings);

        sortStrings = new string[5] { "pmrank", "salesrank", "price", "-price", "titlerank" };
        searchIndexWithSortValues.Add("Software", sortStrings);

        sortStrings = new string[6] { "relevancerank", "salesrank", "pricerank", "inverseprice", "launch-date", "sale-flag" };
        searchIndexWithSortValues.Add("SportingGoods", sortStrings);

        sortStrings = new string[6] { "price", "salesrank", "price", "-price", "titlerank", "-titlerank" };
        searchIndexWithSortValues.Add("Tools", sortStrings);

        sortStrings = new string[6] { "pmrank", "salesrank", "price", "-price", "titlerank", "-age-min" };
        searchIndexWithSortValues.Add("Toys", sortStrings);

        sortStrings = new string[6] { "relevancerank", "salesrank", "price", "-price", "titlerank", "-video-release-date" };
        searchIndexWithSortValues.Add("UnboxVideo", sortStrings);

        sortStrings = new string[7] { "relevancerank", "salesrank", "price", "-price", "titlerank", "-video-release-date", "-releasedate" };
        searchIndexWithSortValues.Add("VHS", sortStrings);

        sortStrings = new string[7] { "relevancerank", "salesrank", "price", "-price", "titlerank", "-video-release-date", "-releasedate" };
        searchIndexWithSortValues.Add("Video", sortStrings);

        sortStrings = new string[5] { "pmrank", "salesrank", "price", "-price", "titlerank" };
        searchIndexWithSortValues.Add("VideoGames", sortStrings);

        sortStrings = new string[5] { "relevancerank", "salesrank", "price", "-price", "reviewrank" };
        searchIndexWithSortValues.Add("Watches", sortStrings);

        sortStrings = new string[7] { "daterank", "pricerank", "inverse-pricerank", "reviewrank", "salesrank", "titlerank", "-titlerank" };
        searchIndexWithSortValues.Add("Wireless", sortStrings);


        sortStrings = new string[4] { "psrank", "salesrank", "titlerank", "-titlerank" };
        searchIndexWithSortValues.Add("WirelessAccessories", sortStrings);


        return searchIndexWithSortValues;
    }

    public static AWSECommerceServicePortTypeClient GetAmazonClient()
    {
        //TODO ensure 1000 milliseconds timeout
        if (clientCanBeCalledAgain)
        {
        }

        BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
        binding.ReaderQuotas.MaxStringContentLength = 4000000;

        binding.MaxReceivedMessageSize = int.MaxValue;
        AWSECommerceServicePortTypeClient client = new AWSECommerceServicePortTypeClient(
            binding,
            new EndpointAddress("https://webservices.amazon.com/onca/soap?Service=AWSECommerceService"));

        // add authentication to the ECS client
        client.ChannelFactory.Endpoint.Behaviors.Add(new AmazonSigningEndpointBehavior(accessKey, secretKey));
        return client;
    }

    public static ItemLookup CreateItemLookup(ItemLookupRequest itemLookupRequest)
    {
        ItemLookup result = new ItemLookup();
        result.AssociateTag = associateTag;
        result.AWSAccessKeyId = accessKey;
        result.Request = new ItemLookupRequest[] { itemLookupRequest };

        return result;
    }

    public static BrowseNodeLookup CreateBrowseNodeLookup(BrowseNodeLookupRequest request)
    {
        BrowseNodeLookup result = new BrowseNodeLookup();
        result.AWSAccessKeyId = accessKey;
        result.AssociateTag = associateTag;
        result.Request = new BrowseNodeLookupRequest[] { request };

        return result;
    }

    public static ItemSearch CreateItemSearch(ItemSearchRequest itemSearchRequest)
    {
        ItemSearch result = new ItemSearch();
        result.AWSAccessKeyId = accessKey;
        result.AssociateTag = associateTag;
        result.Request = new ItemSearchRequest[] { itemSearchRequest };

        return result;
    }

    public static CartModify CreateCartModify(CartModifyRequest cartModifyRequest)
    {
        CartModify result = new CartModify();
        result.AWSAccessKeyId = accessKey;
        result.AssociateTag = associateTag;
        result.Request = new CartModifyRequest[] { cartModifyRequest };

        return result;
    }

    public static CartAdd CreateCartAdd(CartAddRequest cartAddRequest)
    {
        CartAdd result = new CartAdd();
        result.AWSAccessKeyId = accessKey;
        result.AssociateTag = associateTag;
        result.Request = new CartAddRequest[] { cartAddRequest };

        return result;
    }

    public static CartCreate CreateCartCreate(CartCreateRequest cartCreateRequest)
    {
        CartCreate result = new CartCreate();
        result.AWSAccessKeyId = accessKey;
        result.AssociateTag = associateTag;
        result.Request = new CartCreateRequest[] { cartCreateRequest };
        return result;
    }

    public static Items GetProductsForNodeByNodeIdAndSort(string id, string sort)
    {
        return null;
    }

    public static BrowseNode[] GetChildBrowseNodes(string nodeid)
    {
        string cacheKey = nodeid + "GetChildBrowseNodes";
        BrowseNode[] result = null;


        result = DBCache[cacheKey] as BrowseNode[];
        if (result == null)
        {
            result = GetChildBrowseNodesFromAmazon(nodeid);

            DBCache.Add(cacheKey, result, CacheItemPriority.High, null, null);
        }
        return result;
    }

    public static BrowseNode[] GetChildBrowseNodesFromAmazon(string nodeid)
    {
        BrowseNode[] result = null;
        BrowseNodeLookupRequest request = new BrowseNodeLookupRequest();
        AWSECommerceServicePortTypeClient client = AmazonHelper.GetAmazonClient();
        // Create ItemSearch wrapper
        BrowseNodeLookup nodeLookup = new BrowseNodeLookup();
        nodeLookup.AssociateTag = associateTag;
        nodeLookup.AWSAccessKeyId = accessKey;
        nodeLookup.Request = new BrowseNodeLookupRequest[] { request };

        request.BrowseNodeId = new string[] { nodeid };
        nodeLookup.Request = new BrowseNodeLookupRequest[] { request };

        BrowseNodeLookupResponse response = client.BrowseNodeLookup(nodeLookup);
        if (response.BrowseNodes[0].BrowseNode != null
            && response.BrowseNodes[0].BrowseNode[0].Children != null)
        {
            result = response.BrowseNodes[0].BrowseNode[0].Children;
        }
        return result;
    }

    public static Item GetProductDetail(string productASIN)
    {
        string cacheKey = productASIN + "GetProductDetail";
        Item result;

        result = WebCache[cacheKey] as Item;
        if (result == null)
        {
            result = GetProductDetailFromAmazon(productASIN);
            if (result == null)
            {
                HttpContext.Current.Response.StatusCode = 301;
                HttpContext.Current.Response.Redirect("~/");

            }
            //WebCache.Add(cacheKey, result, CacheItemPriority.Low,null, null);
            WebCache.Add(cacheKey, result, null, DateTime.MaxValue, ProductDetailsCacheExpiration, System.Web.Caching.CacheItemPriority.Low, null);
        }
        return result;
    }

    public static Item GetProductDetailFromAmazon(string productASIN)
    {

        ItemLookupRequest request = new ItemLookupRequest();
        request.ItemId = new string[] { productASIN };
        request.Condition = Condition.All;
        request.ResponseGroup = GetItemLookupResponseGroups();
        request.IdType = ItemLookupRequestIdType.ASIN;
        request.MerchantId = "All";
        //request.ReviewSort = "-HelpfulVotes";
        ItemLookup lookup = CreateItemLookup(request);
        AWSECommerceServicePortTypeClient client = GetAmazonClient();
        ItemLookupResponse response = client.ItemLookup(lookup);
        Item result = null;
        if (response.Items[0].Item != null && response.Items[0].Item.GetLength(0) > 0)
        {
            result = response.Items[0].Item[0];
        }




        return result;
    }

    public static Item GetProductDetailWithReviews(string productASIN, string reviewPage, string reviewSort)
    {

        string cacheKey = productASIN + "GetProductDetail" + reviewPage + reviewSort;
        Item result;
        result = WebCache[cacheKey] as Item;
        if (result == null)
        {
            result = GetProductDetailFromAmazonWithReviews(productASIN, reviewPage, reviewSort);

            //AspCache.Add(cacheKey, result, CacheItemPriority.Low, null, null);
            WebCache.Add(cacheKey, result, null, DateTime.MaxValue, TimeSpan.FromMinutes(5), System.Web.Caching.CacheItemPriority.High, null);

        }
        return result;


    }

    public static Item GetProductDetailFromAmazonWithReviews(string productASIN, string reviewPage, string reviewSort)
    {

        //Default: -SubmissionDate

        //Valid Values: -HelpfulVotes | HelpfulVotes | -OverallRating | OverallRating | SubmissionDate


        ItemLookupRequest request = new ItemLookupRequest();
        request.ItemId = new string[] { productASIN };
        request.Condition = Condition.All;
        request.ResponseGroup = GetItemLookupResponseGroups();
        request.IdType = ItemLookupRequestIdType.ASIN;
        request.MerchantId = "All";
        //request.ReviewPage = reviewPage;
        //if (reviewSort == "")
        //{
        //    reviewSort = "-HelpfulVotes";
        //}
        //request.ReviewSort = reviewSort;
        ItemLookup lookup = CreateItemLookup(request);
        AWSECommerceServicePortTypeClient client = GetAmazonClient();
        ItemLookupResponse response = client.ItemLookup(lookup);
        Item result = response.Items[0].Item[0];

        return result;
    }

    public static string[] GetItemLookupResponseGroupsForList()
    {
        return new string[] { 
            //"Accessories", 
            //"BrowseNodes",
            //"EditorialReview", 
            //"Images",
            //"ItemAttributes", 
            //"ItemIds", 
            //"Large", 
            //"ListmaniaLists", 
            "Medium", 
            //"MerchantItemAttributes", 
            "OfferFull", 
            //"PromotionDetails", 
            //"PromotionSummary", 
            //"OfferSummary",
            //"RelatedItems", 
            //"Reviews", 
            //"SalesRank", 
            //"Similarities", 
            //"Subjects",            
            //"Tags", 
            //"TagsSummary", 
            //"Tracks",
            //"VariationImages", 
            //"VariationMinimum", 
            //"Variations", 
            //"VariationSummary" 
        };
    }

    public static string[] GetItemLookupResponseGroups()
    {
        return new string[] { 
            //"Accessories", 
            //"BrowseNodes",
            //"EditorialReview", 
            //"Images",
            //"ItemAttributes", 
            //"ItemIds", 
            "Large", 
            //"ListmaniaLists", 
            //"Medium", 
            //"MerchantItemAttributes", 
            "OfferFull", 
            //"Offers", 
            //"PromotionDetails", 
            //"PromotionSummary", 
            //"OfferSummary",
            //"RelatedItems", 
            "Reviews", 
            "SalesRank", 
            //"Similarities", 
            //"Subjects",            
            //"Tags", 
            //"TagsSummary", 
            //"Tracks",
            "VariationImages", 
            //"VariationMinimum", 
            "Variations", 
            //"VariationSummary" 
        };
    }


    public static Items GetProductsForKeyWord(string searchTerm)
    {

        Items result = null;
        string cacheKey = searchTerm + "GetProductsForKeyWord";

        result = WebCache[cacheKey] as Items;
        if (result == null)
        {
            result = GetProductsForKeyWordFromAmazon(searchTerm);
            WebCache.Add(cacheKey, result, null, DateTime.MaxValue, TimeSpan.FromMinutes(5), System.Web.Caching.CacheItemPriority.Low, null);
        }
        return result;
    }

    private static Items GetProductsForKeyWordFromAmazon(string searchTerm)
    {
        AWSECommerceServicePortTypeClient client = GetAmazonClient();
        // Create ItemSearch wrapper
        ItemSearch itemSearch = new ItemSearch();
        itemSearch.AssociateTag = associateTag;
        itemSearch.AWSAccessKeyId = accessKey;


        ItemSearchRequest itemSearchRequest = new ItemSearchRequest();
        List<string> responseGroups = new List<string>();
        responseGroups.Add("Large");
        responseGroups.Add("Offers");
        responseGroups.Add("Reviews");

        itemSearchRequest.ResponseGroup = responseGroups.ToArray();
        itemSearchRequest.MerchantId = "All";
        //itemSearchRequest.Count = showItemsPerPage.ToString();
        itemSearchRequest.Availability = ItemSearchRequestAvailability.Available;
        itemSearchRequest.Condition = Condition.All;
        itemSearchRequest.SearchIndex = "All";

        itemSearchRequest.Keywords = searchTerm;
        itemSearch.Request = new ItemSearchRequest[] { itemSearchRequest };


        Items result = null;

        ItemSearchResponse itemSearchResponse = client.ItemSearch(itemSearch);

        result = itemSearchResponse.Items[0];

        return result;
    }

    private static TimeSpan ProductDetailsCacheExpiration = TimeSpan.FromHours(6);



}
